package misc

import (
	"dhfshop/controllers/base"
	"dhfshop/models/isv"
	"dhfshop/service/redisgo"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/validation"
	"strconv"
	"time"
	"wxsdk/mp/jssdk"
	"wxsdk/wxpay/utils/pay"
)

type JsSdkController struct {
	base.BaseController
}

func (this *JsSdkController) Get() {
	v := struct {
		AppId string `form:"app_id" valid:"Required"`
		Url   string `form:"url"  valid:"Required"`
	}{}
	this.ParseForm(&v)
	valid := validation.Validation{}
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key + " " + valid.Errors[0].Message)
		return
	}
	custAccount, err := isv.GetCustAccountByAppId(v.AppId)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	curTime := time.Now().Unix()
	ticketStr, err := GetJsTicketFromCache(v.AppId, custAccount.AccessToken, curTime)
	if err != nil {
		this.ServeError(err.Error())
		return
	}
	nonceStr := payutils.GetNonceStr(32) //随机字符串
	timestamp := strconv.FormatInt(curTime, 10)
	signature := jssdk.WXConfigSign(ticketStr, nonceStr, timestamp, v.Url)
	rsp := struct {
		AppId     string `json:"app_id"`
		Timestamp int64  `json:"timestamp"`
		NonceStr  string `json:"nonceStr"`
		Signature string `json:"signature"`
	}{AppId: v.AppId, Timestamp: curTime, NonceStr: nonceStr, Signature: signature}
	this.Data["json"] = rsp
	this.ServeJSON()
}

// 从缓存中读取单个用户数据
func GetJsTicketFromCache(appId, accessToken string, curTime int64) (ticket string, err error) {
	var cacheTicket struct {
		Ticket      string `json:"ticket"`
		ExpiresTime int64  `json:"expires_time"`
	}
	cacheKey := fmt.Sprintf("%s", appId)
	redisconn := redisgo.GetInstance()
	//
	if cacheValue, e := redisconn.GetString(cacheKey); e == nil && len(cacheValue) > 20 {
		//beego.Debug("cache ticket", cacheValue)
		if err = json.Unmarshal([]byte(cacheValue), &cacheTicket); err == nil {
			refTime := time.Unix(curTime, 0).Add(time.Minute * 5) //预留5分钟
			if cacheTicket.ExpiresTime > refTime.Unix() {
				ticket = cacheTicket.Ticket
				return
			}
		}
	}
	// 需要从微信服务器请求
	jsapiTicket, e := jssdk.UpdateTicket(accessToken)
	if e != nil {
		err = e
		return
	}
	ticket = jsapiTicket.Ticket
	// 缓存
	cacheTicket.Ticket = jsapiTicket.Ticket
	cacheTicket.ExpiresTime = curTime + jsapiTicket.ExpiresIn
	if cacheJSON, err := json.Marshal(&cacheTicket); err == nil {
		if _, err = redisconn.Set(cacheKey, string(cacheJSON), 2*3600); err != nil {
			beego.Debug("SETEX", err.Error())
		}
	}
	return
}
